package net.xdclass.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import net.xdclass.controller.request.TrafficPageRequest;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.enums.EventMessageType;
import net.xdclass.exception.BizException;
import net.xdclass.feign.ProductFeignService;
import net.xdclass.interceptor.LoginInterceptor;
import net.xdclass.manager.TrafficManager;
import net.xdclass.mapper.TrafficMapper;
import net.xdclass.model.EventMessage;
import net.xdclass.model.LoginUser;
import net.xdclass.model.TrafficDO;
import net.xdclass.service.TrafficService;
import net.xdclass.util.IDUtil;
import net.xdclass.util.JsonData;
import net.xdclass.vo.ProductVO;
import net.xdclass.vo.TrafficVO;
import org.springframework.beans.BeanUtils;
import org.springframework.data.keyvalue.repository.KeyValueRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLIntegrityConstraintViolationException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Allen
 * @version 1.0
 * @date 2022/12/7 12:05
 */
@Service
@Slf4j
public class TrafficServiceImpl implements TrafficService {


	@Resource
	private ProductFeignService productFeignService;

	@Resource
	private TrafficManager trafficManager;
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean handleTrafficMessage(EventMessage eventMessage) {

		String eventMessageType = eventMessage.getEventMessageType();

		if (eventMessageType.equalsIgnoreCase(EventMessageType.PRODUCT_ORDER_PAY.name())) {
			String content = eventMessage.getContent();
			Long accountNo = eventMessage.getAccountNo();
			String outTradeNo = eventMessage.getBizId();

			Map map = JSONUtil.toBean(content, Map.class);
			Integer buyNum = (Integer)map.get("buyNum");
			String productSnapshotStr = (String)map.get("product");
			ProductVO productVO = JSONUtil.toBean(productSnapshotStr, ProductVO.class);



			//流量包有效期
			LocalDateTime expiredDateTime = LocalDateTime.now().plusDays(productVO.getValidDay());
			Date date = Date.from(expiredDateTime.atZone(ZoneId.systemDefault()).toInstant());


			//构建流量包对象
			TrafficDO trafficDO = TrafficDO.builder()
				.accountNo(accountNo)
				.dayLimit(productVO.getDayTimes() * buyNum)
				.dayUsed(0)
				.totalLimit(productVO.getTotalTimes())
				.pluginType(productVO.getPluginType())
				.level(productVO.getLevel())
				.productId(productVO.getId())
				.outTradeNo(outTradeNo)
				.expiredDate(date).build();

			try {
				int rows = trafficManager.add(trafficDO);
			} catch (Exception e) {
				log.error("插入失败：{}",JSONUtil.toJsonStr(e));

			}

			log.info("消费消息新增流量包: trafficDO={}",trafficDO);


		}
		else if (eventMessageType.equalsIgnoreCase(EventMessageType.TRAFFIC_FREE_INIT.name())) {
			Long productId = Long.valueOf(eventMessage.getBizId());
			Long accountNo = eventMessage.getAccountNo();

			JsonData jsonData =
				productFeignService.detail(productId);
			ProductVO productVO = jsonData.getData(new TypeReference<ProductVO>() {});
			/*{"id":1,
			"title":"青铜会员-默认",
			"detail":"数据查看支持||日生成短链{{dayTimes}}次||限制跳转50次||默认域名",
			"level":"FIRST",
			"oldAmount":19,
			"amount":0,
			"pluginType":"SHORT_LINK",
			"dayTimes":2,
			"validDay":1,
			"gmtModified":"2021-10-14T09:33:44.000+00:00",
			"gmtCreate":"2021-10-11T02:49:35.000+00:00"}*/
			//构建流量包对象
			TrafficDO trafficDO = TrafficDO.builder()
				.accountNo(accountNo)
				.dayLimit(productVO.getDayTimes())
				.dayUsed(0)
				.totalLimit(productVO.getTotalTimes())
				.pluginType(productVO.getPluginType())
				.level(productVO.getLevel())
				.productId(productVO.getId())
				.outTradeNo("free-init")
				.expiredDate(new Date()).build();

			try {
				int rows = trafficManager.add(trafficDO);
			} catch (Exception e) {
				log.error("插入失败：{}",JSONUtil.toJsonStr(e));

			}

			log.info("消费消息新增流量包: trafficDO={}",trafficDO);


		}

		return Boolean.TRUE;
	}

	@Override
	public Map<String, Object> pageAvailable(TrafficPageRequest request) {

		int size = request.getSize();
		int page = request.getPage();
		LoginUser loginUser = LoginInterceptor.threadLocal.get();

		IPage<TrafficDO> trafficDOIPage = trafficManager.pageAvailable(page, size, loginUser.getAccountNo());

		//获取流量包列表
		List<TrafficDO> records = trafficDOIPage.getRecords();

		List<TrafficVO> trafficVOList = records.stream().map(this::beanProcess).collect(Collectors.toList());

		Map<String, Object> pageMap = new HashMap<>(3);
		pageMap.put("total_record", trafficDOIPage.getTotal());
		pageMap.put("total_page",trafficDOIPage.getPages());
		pageMap.put("current_data",trafficVOList);

		return pageMap;
	}


	@Override
	public TrafficVO detail(long trafficId) {
		LoginUser loginUser = LoginInterceptor.threadLocal.get();

		TrafficDO trafficDO = trafficManager.findByIdAndAccountNo(trafficId, loginUser.getAccountNo());

		return beanProcess(trafficDO);
	}


	private TrafficVO beanProcess(TrafficDO trafficDO) {

		TrafficVO trafficVO = new TrafficVO();
		BeanUtils.copyProperties(trafficDO,trafficVO);
		return trafficVO;
	}
}
